import { ref, computed, ComputedRef, unref } from 'vue';
import { useEventListener } from '/@/hooks/event/useEventListener';
import { screenMap, sizeEnum, screenEnum } from '/@/enums/breakpointEnum';

let globalScreenRef: ComputedRef<sizeEnum | undefined>;
let globalWidthRef: ComputedRef<number>;
let globalRealWidthRef: ComputedRef<number>;

export interface CreateCallbackParams {
   screen: ComputedRef<sizeEnum | undefined>;
   width: ComputedRef<number>;
   realWidth: ComputedRef<number>;
   screenEnum: typeof screenEnum;
   screenMap: Map<sizeEnum, number>;
   sizeEnum: typeof sizeEnum;
}

export function useBreakpoint() {
   return {
      screenRef: computed(() => unref(globalScreenRef)),
      widthRef: globalWidthRef,
      screenEnum,
      realWidthRef: globalRealWidthRef,
   };
}

// Just call it once
export function createBreakpointListen(fn?: (opt: CreateCallbackParams) => void) {
   const screenRef = ref<sizeEnum>(sizeEnum.XL);
   const realWidthRef = ref(window.innerWidth);

   function getWindowWidth() {
      const width = document.body.clientWidth;
      const xs = screenMap.get(sizeEnum.XS)!;
      const sm = screenMap.get(sizeEnum.SM)!;
      const md = screenMap.get(sizeEnum.MD)!;
      const lg = screenMap.get(sizeEnum.LG)!;
      const xl = screenMap.get(sizeEnum.XL)!;
      if (width < xs) {
         screenRef.value = sizeEnum.XS;
      } else if (width < sm) {
         screenRef.value = sizeEnum.SM;
      } else if (width < md) {
         screenRef.value = sizeEnum.MD;
      } else if (width < lg) {
         screenRef.value = sizeEnum.LG;
      } else if (width < xl) {
         screenRef.value = sizeEnum.XL;
      } else {
         screenRef.value = sizeEnum.XXL;
      }
      realWidthRef.value = width;
   }

   useEventListener({
      el: window,
      name: 'resize',

      listener: () => {
         getWindowWidth();
         resizeFn();
      },
      // wait: 100,
   });

   getWindowWidth();
   globalScreenRef = computed(() => unref(screenRef));
   globalWidthRef = computed((): number => screenMap.get(unref(screenRef)!)!);
   globalRealWidthRef = computed((): number => unref(realWidthRef));

   function resizeFn() {
      fn?.({
         screen: globalScreenRef,
         width: globalWidthRef,
         realWidth: globalRealWidthRef,
         screenEnum,
         screenMap,
         sizeEnum,
      });
   }

   resizeFn();
   return {
      screenRef: globalScreenRef,
      screenEnum,
      widthRef: globalWidthRef,
      realWidthRef: globalRealWidthRef,
   };
}
